home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
BG_SRC.ZIP
/
BG_GMOV.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-09
|
9KB
|
240 lines
/*
* B G _ G M O V . C
* The graphics of moving and placing the pieces
* O.F.Ransen: 11th September 1991
* This version: 9th January 1993
*/
#include "comp.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "bg.h"
/***************************************************************************/
static void Show_Move (short Old_Point, short Moves,
short Old_Row, short New_Row,
Player_t Player) ;
static void Endpix_To_Circle (double* Start_Ang, short Center[TWOD_COORDS],
double* Rad, short Sta[TWOD_COORDS], short End[TWOD_COORDS]) ;
static void Make_Scircle_Pline (short Pline [NSC_POINTS][TWOD_COORDS],
short Center [TWOD_COORDS], double Rad,
double Angle, double Delta_Ang) ;
static void Make_Straight_Pline (short Pline [NSC_POINTS][TWOD_COORDS],
short Sta[TWOD_COORDS], short End[TWOD_COORDS]) ;
static void Draw_XOR_Pline (short Pline[NSC_POINTS][TWOD_COORDS]) ;
static void Weighted_Average_Line (short Line0 [NSC_POINTS][TWOD_COORDS],
short Line1 [NSC_POINTS][TWOD_COORDS],
short Line0_Power) ;
/***************************************************************************/
void Draw_Transits (Transit_t* Me, Transit_t* Him, Player_t Player)
/*
PURPOSE: To show the moves contained in the transit types. Me will
make bewteen 0 to 4 moves, and Him will make as many as pieces Me has
eaten. Me moves are in semicirles, Him moves are straight lines to the
bar.
*/
{
short m ;
if ((Me->N_Moves > 4) || (Me->N_Moves < 0)) {
printf ("\nERROR: Me->N_Moves=%d in Draw_Transits.",Me->N_Moves) ;
Error_Exit ("Bad Me->N_Moves in Draw_Transits") ;
}
if ((Him->N_Moves > 4) || (Him->N_Moves < 0)) {
printf ("\nERROR: Him->N_Moves=%d in Draw_Transits.",Him->N_Moves) ;
Error_Exit ("Bad Him->N_Moves in Draw_Transits") ;
}
/* Show my moves */
for (m = 0 ; m < Me->N_Moves ; m++) {
Show_Move (Me->Old_Points[m],
Me->Places_Movd[m],
Me->Old_Row[m],
Me->New_Row[m],
Player) ;
}
/* Show his moves (only if I have eaten recently) */
for (m = 0 ; m < Him->N_Moves ; m++) {
Show_Move (Him->Old_Points[m],
Him->Places_Movd[m],
Him->Old_Row[m],
Him->New_Row[m],
OPPONENT(Player)) ;
}
}
/***************************************************************************/
static void Show_Move (short Old_Point, short Moves,
short Old_Row, short New_Row,
Player_t Player)
/*
PURPOSE: To graphically show the motion described in the input parameters
*/
{
short Start [TWOD_COORDS],End[TWOD_COORDS],Center[TWOD_COORDS] ;
double Start_Ang,Radius,Delta_Ang ;
short Pline [NSC_POINTS][TWOD_COORDS] ;
short Circular_Pline [NSC_POINTS][TWOD_COORDS] ;
Get_Piece_Center (&Start[XI],&Start[YI],Player,Old_Point,Old_Row,Old_Row+1,GRID_ROWS/2) ;
Get_Piece_Center (&End[XI], &End[YI], Player,Old_Point+Moves,New_Row,New_Row+1,GRID_ROWS/2) ;
Make_Straight_Pline (Pline,Start,End) ;
if (Old_Point + Moves > HOME_I) {
Error_Exit ("In Show_Move, Old_Point + Moves > HOME_I.") ;
} else if ((Old_Point + Moves != BAR_I) && (Old_Point != BAR_I)) {
/* Add some circular motion */
if (Player == BLACK_PLAYER) {
Delta_Ang = DELTA_ANGLE ; /* Anti clockwise */
} else {
Delta_Ang = (-DELTA_ANGLE) ; /* Clockwise */
}
Endpix_To_Circle (&Start_Ang, Center, &Radius, Start, End) ;
Make_Scircle_Pline (Circular_Pline, Center, Radius, Start_Ang, Delta_Ang) ;
Weighted_Average_Line (Pline,Circular_Pline,8) ;
}
Draw_XOR_Pline (Pline) ;
}
/***************************************************************************/
static void Endpix_To_Circle (double* Start_Ang, short Center[TWOD_COORDS], double* Radius,
short Start[TWOD_COORDS], short End[TWOD_COORDS])
/*
PURPOSE: Give the coords of the extremes of a semicircle we return the
starting angle and the center of the semicircle.
NOTES: 1) This does not specify the direction of rotation.
2) 0 degrees is to the East, 90 degrees is to the North.
3) 0,0 is always at top left.
4) Circles go from 0..360 degrees, anticlockwise, not +-180
*/
{
short c ;
short Diff[TWOD_COORDS] ;
double Ang,Diff_2[TWOD_COORDS] ;
for (c = XI ; c <= YI ; c++) {
Center [c] = (Start[c] + End[c]) / 2 ;
Diff [c] = Start[c] - End[c] ;
Diff_2 [c] = (double)Diff[c] * (double)Diff[c] ;
}
(*Radius) = (sqrt (Diff_2[XI] + Diff_2[YI])) ;
Ang = asin (-(double)Diff[YI]/(*Radius)) ;
(*Radius) = (*Radius)/2.0 ;
if (Ang < 0.0) { /* In lower 2 quadrants */
if (Start[XI] < End[XI]) { /* In lower left quad */
(*Start_Ang) = PI - Ang ;
} else {
(*Start_Ang) = TWO_PI + Ang ;
}
} else { /* In upper 2 quadrants */
if (Start[XI] < End[XI]) { /* In upper left quadrant */
(*Start_Ang) = PI - Ang ;
} else {
(*Start_Ang) = Ang ;
}
}
}
/***************************************************************************/
static void Make_Scircle_Pline (short Pline [NSC_POINTS][TWOD_COORDS],
short Center [TWOD_COORDS], double Radius,
double Angle, double Delta_Ang)
/*
PURPOSE: To fill in the Pline with points on a semicircle, staring
at Angle and incrementing by Delta_Ang.
NOTES: 1) Delta_Ang can be +ve or -ve, +ve Deltas move anticlockwise.
*/
{
short p ;
for (p = 0 ; p < NSC_POINTS ; p++) {
Pline[p][XI] = Center[XI] + (short)(Radius*cos(Angle)) ;
Pline[p][YI] = Center[YI] - (short)(Radius*sin(Angle)) ;
Angle += Delta_Ang ;
}
}
/***************************************************************************/
static void Make_Straight_Pline (short Pline [NSC_POINTS][TWOD_COORDS],
short Start[TWOD_COORDS], short End[TWOD_COORDS])
/*
PURPOSE: To make a set of points from the start to the end.
*/
{
short i,c, Delta[TWOD_COORDS] ;
for (c = 0 ; c < TWOD_COORDS ; c++) {
Delta[c] = End[c] - Start[c] ;
}
for (i = 0 ; i < NSC_POINTS ; i++) {
for (c = 0 ; c < TWOD_COORDS ; c++) {
Pline [i][c] = Start[c] + (i*Delta[c]/(NSC_POINTS-1)) ;
}
}
}
/***************************************************************************/
#if DRODBAR
void Draw_Dotted_Pline (short Pline[NSC_POINTS][TWOD_COORDS], short Colour)
/*
PURPOSE: To XOR draw the dots in the poly line handed to us.
*/
{
ushort p ;
for (p = 0 ; p < NSC_POINTS ; p++) {
Draw_Point (Pline[p][XI],Pline[p][YI],Colour) ;
}
}
#endif
/***************************************************************************/
static void Draw_XOR_Pline (short Pline[NSC_POINTS][TWOD_COORDS])
/*
PURPOSE: To XOR draw the dots in the poly line handed to us.
*/
{
ushort p ;
setwritemode (XOR_PUT) ;
setcolor (WHITE) ;
for (p = 0 ; p < NSC_POINTS-1 ; p++) {
line (Pline[p][XI],Pline[p][YI],Pline[p+1][XI],Pline[p+1][YI]) ;
}
setwritemode (COPY_PUT) ;
}
/***************************************************************************/
static void Weighted_Average_Line (short Line0 [NSC_POINTS][TWOD_COORDS],
short Line1 [NSC_POINTS][TWOD_COORDS],
short Line0_Power)
/*
PURPOSE: To form a weighted average of Line0 and Line1, making the changes
in Line0. Line0_Power should be between 0 and 10.
*/
{
short p,c ;
for (p = 0 ; p < NSC_POINTS ; p++) {
for (c = 0 ; c < TWOD_COORDS ; c++) {
Line0[p][c] = (Line0[p][c] * Line0_Power) +
(Line1[p][c] * (10 - Line0_Power)) ;
Line0[p][c] = Line0[p][c] / 10 ;
}
}
}
/***************************************************************************/